<?php

namespace src\database\connectors;

use InvalidArgumentException;
use src\database\MySqlConnection;

class DbFactory
{

    /**
     * 生产方法
     * @param $config
     * @param $name
     * @return MySqlConnection
     */
    public function make($config, $name = null)
    {
        $config = $this->parseConfig($config, $name);
        if (isset($config['read'])){
            return $this->createReadWriteConnection($config);
        }
        return $this->createSingleConnection($config);
    }


    //添加
    protected function parseConfig($config, $name)
    {
        if (!isset($config['prefix'])){
            $config['prefix'] = '';
        }
        if ($name){
            $config['name'] = $name;
        }
        return $config;
    }


    //获取读写连接对象
    protected function createReadWriteConnection($config)
    {
        $connection = $this->createSingleConnection($this->getWriteConfig($config));
        return $connection->setReadPdo($this->createReadPdo($config));
    }

    protected function createReadPdo($config)
    {
        return $this->createPdoResolver($this->getReadConfig($config));
    }

    protected function createPdoResolver($config)
    {
        return function () use ($config) {
            return $this->createConnector($config)->connect($config);
        };
    }

    protected function getReadConfig($config)
    {
        $read = $this->getReadWriteConfig($config, 'read');
        unset($config['write'], $config['read']);
        return array_merge($config, $read);
    }

    //获取读配置文件
    protected function getWriteConfig($config)
    {
        $write = $this->getReadWriteConfig($config, 'write');
        unset($config['write'], $config['read']);
        return array_merge($config, $write);
    }

    /**
     * 获取读写配置
     * @param $config
     * @param string $type read | write
     * @return mixed
     */
    protected function getReadWriteConfig($config, $type)
    {
        if (isset($config[$type][0])){
            return $config[$type][array_rand($config[$type], 1)];
        }else{
            return $config[$type];
        }
    }


    //创建连接
    protected function createSingleConnection($config)
    {
        $connection =  $this->createPdoResolver($config);
        return $this->createConnection(
            $config['driver'], $connection, $config['database'], $config['prefix'], $config
        );
    }

    protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
    {
        switch ($driver) {
            case 'mysql':
                return new MySqlConnection($connection, $database, $prefix, $config);
            default:
                throw new \Exception("不支持{$driver} 驱动");
        }
    }

    protected function createConnector($config)
    {
        if (!isset($config['driver'])) {
            throw new InvalidArgumentException('A driver must be specified.');
        }
        return new MySqlConnector;
    }
}